grammar tproto;

@parser::members
{
protected const int EOF = Eof;
}
 
@lexer::members
{
protected const int EOF = Eof;
protected const int HIDDEN = Hidden;
}


/*
 * Parser Rules
 */
 
program: packageDeclaration importDeclaration* protocolDeclaration+ EOF;

packageDeclaration: PACKAGE qualifiedName ';';

importDeclaration: IMPORT qualifiedName ('.' '*')? ';';

protocolDeclaration: noteDeclaration* PROTOCOL IDENTIFIER '{' fieldDeclaration* '}';

fieldDeclaration: typeDeclaration IDENTIFIER ';' noteDeclaration*;

typeDeclaration: TYPE_BASE | TYPE_BASE '[]' | IDENTIFIER | IDENTIFIER '[]';

noteDeclaration : COMMENT|LINE_COMMENT;

qualifiedName: IDENTIFIER ('.' IDENTIFIER)*;

/*
 * Lexer Rules
 */
PROTOCOL: 'message';
IMPORT: 'import';
PACKAGE: 'module';

TYPE_BASE: TYPE_BOOL | TYPE_CHAR | TYPE_BYTE | TYPE_SHORT | TYPE_INT | TYPE_LONG | TYPE_FLOAT | TYPE_DOUBLE | TYPE_STRING;
TYPE_BOOL: 'boolean';
TYPE_CHAR: 'char';
TYPE_BYTE: 'byte';
TYPE_SHORT: 'short';
TYPE_INT: 'int';
TYPE_LONG: 'long';
TYPE_FLOAT: 'float';
TYPE_DOUBLE: 'double';
TYPE_STRING: 'String';

IDENTIFIER: Letter LetterOrDigit*; 

WS:				[ \t\u000C\r\n]+ -> skip;
COMMENT:		'/*' .*? '*/'    ;
LINE_COMMENT:	'//' ~[\r\n]*    ;




fragment LetterOrDigit: Letter|Digit;
fragment Digit: [0-9];
fragment Letter: [a-zA-Z_];

